import { app, shell, BrowserWindow , ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import { handleLoginOrRegister, onOpenChat , onOperateWindow  } from './ipc'

import store from './store'
import db from './db'
import SessionService from './service/session'
import MessageService from './service/chat'
import ContactService from './service/contact'
import { formatTime } from './util'
import userStore from './store/user'
import CallUtil from './util/call'

const login_width = 300
const login_height = 370
const register_height = 490

// 子窗口们
const childWindows = {}

function createNewWindow(route , parent , config) {

  const oldWin = childWindows[route]
  if (oldWin != null && !oldWin.isDestroyed()) {
    oldWin.focus()
  } else {
    const { width = 350, height = 600 , fromParent } = config
    const win = new BrowserWindow({
      width: width,
      height: height,
      titleBarStyle: 'hidden',
      autoHideMenuBar: true,
      frame:true,
      resizable: false,
      alwaysOnTop: false,
      parent: fromParent ? parent : null,
      modal:false,
      webPreferences: {
        // 去除上下文隔离
        contextIsolation: false,
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false
      }
    })

    childWindows[route] = win;

    // 开发环境 URL（HMR）
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      win.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/#${route}`)
    } else {
      // 生产环境加载打包后的 index.html
      win.loadFile(join(__dirname, '../renderer/index.html'), {
        hash: route, // 直接跳转到对应路由
      })
    }
    win.on('ready-to-show', () => {
      win.focus()
    })

  }


}

function createWindow() {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    icon: icon,
    width: login_width,
    height: login_height,
    show: false,
    autoHideMenuBar: true,
    alwaysOnTop: false,
    resizable: false,
    frame:true,
    transparent: false,
    titleBarStyle: 'hidden',
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      // 去除上下文隔离
      contextIsolation: false,
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })





  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
    mainWindow.setTitle("微信")
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }



  // 当切换注册Or登录时
  handleLoginOrRegister((isLogin) => {
    mainWindow.setResizable(true)
    if (isLogin) {
      mainWindow.setSize(login_width , login_height)
    } else {
      mainWindow.setSize(login_width , register_height)
    }
    mainWindow.setResizable(false)
  })

  // 当进入主界面时
  onOpenChat((data) => {
    mainWindow.setResizable(true)
    // mainWindow.setSize(data.screenWidth , data.screenHeight)

    // 可以最大化
    mainWindow.setMaximizable(true)
    // 设置最小窗口大小
    mainWindow.setMinimumSize(1000 , 600)

    if (data.admin) {
      mainWindow.fullScreen = true
    } else {
      mainWindow.setSize(850 , 800)
    }

    // 居中显示
    mainWindow.center()
  })


  function operateWindow(e , data) {
    const win = BrowserWindow.fromWebContents(e.sender) // 获取发送事件的窗口实例
    switch (data) {
      case 'min' : mainWindow.minimize();
        break;
      case 'max' :
        const isFullScreen = mainWindow.isFullScreen()
        if (isFullScreen) {
          mainWindow.setFullScreen(false)
        } else {
          mainWindow.setFullScreen(true)
        }
        break;
      case 'close' :
        win.destroy()
        for (let i in childWindows) {
          if (childWindows[i] === win) {
            delete childWindows[i]
          }
        }
        break;
    }
  }

  // 当进行窗口操作时
  onOperateWindow((e , data) => {
    operateWindow(e , data)
  })

  ipcMain.on('init-user', ( event ,data) => {
    userStore.uid = data.uid
    userStore.nickName = data.nickname
    console.log('用户store:' , userStore.uid)
  })

  /**
   * 当开始新窗口时
   */
  ipcMain.on('open-new-window', (event, route ,  config) => {
    const win = BrowserWindow.fromWebContents(event.sender)
    createNewWindow(route , win , config)
  })

  /**
   * 重新改变窗口大小
   */
  ipcMain.on('window-resize', (event, { width = 350 , height = 550}) => {
    console.log('收到重置窗口大小请求', width, height)
     const win = BrowserWindow.fromWebContents(event.sender)
    win.setResizable(true)
    win.setSize(width, height)
    win.setResizable(false)
  })


  // 创建会话时
  ipcMain.handle('create-session', (event, data) => {
    return sessionService.createSession(event , data);
  })


  // 获取会话列表
  ipcMain.handle('get-session-list', (event, data) => {
    return new Promise((resolve, reject) => {
      const result =  sessionService.getSessionList(data)
      resolve(result)
    })

  })


  // 获取聊天记录列表
  ipcMain.handle('get-chat-list',   (event, data) => {
    return new Promise(async (resolve, reject) => {
      const list = await sessionService.getChatList(data)
      console.log('要返回的list' , list)
      resolve(list)
    })
  })

  // 保存本地消息
  ipcMain.handle('save-message', (event, data) => {
    return messageService.saveMessage(data)
  })

  // 保存好友信息
  ipcMain.handle('save-contact', async (event, data) => {
    console.log('收到保存好友请求')
    const res = await contactService.saveContact(data)
    return res
  })

  // 初始化会话
  ipcMain.handle('init-session',  async (event, data) => {
    const time = Date.now()
    const insertSessionObj = {
      contactId: data.uid,
      createUser: data.userId,
      lastTime: time,
      createTime: time,
      lastAvatar: data.avatar,
      contactName: data.remark
    }
    const sessionId = await sessionService.createSession(event , insertSessionObj)

    const insertContactObj = {
      applyId: data.userId,
      targetId: data.uid,
      remark: data.remark,
      contactInfo: {
        nickname: data.nickname,
        phone: data.phone,
        email: data.email,
        area: data.area,
        areaCode: data.areaCode,
        avatar: data.avatar
      },

      contactRemark: data.remark,
      type: data.contactType,
      friendPermission: data.friendPermission,
      source: '账号搜索添加',
      status: data.status,
      createUser: data.userId,
      createTime: insertSessionObj.createTime
    }
    await contactService.saveContact(insertContactObj)

    console.log('创建的sessionId：' , sessionId )
    const messageObj = {
      sessionId,
      type: 1,
      status: 1,
      isRead:0,
      content: '我们已经成为好友啦，快来找我聊天吧！',
      contactId: data.uid,
      createTime: time,
      createUser: data.userId
    }

    const sessionEntity = {
      sessionId: sessionId,
      contactId: data.uid,
      lastTime:  new Date(time) ,
      lastMessage: messageObj.content,
      createUser: data.userId

    }

    mainWindow.webContents.send('render-send-message' , JSON.parse(JSON.stringify(messageObj)) , sessionEntity)
    console.log('处理完了 关闭窗口')
    BrowserWindow.fromWebContents(event.sender).close();
    return sessionId;
  })


  // 连接初始化会话
  ipcMain.handle('start-init-session' , (event, data) => {
    return sessionService.initSession(data)
  })

  // 连接初始化信息
  ipcMain.handle('start-init-sessionInfo' , (event, data) => {
    return messageService.saveMessage(data)
  })


  // 退出登录
  ipcMain.on('logout', (event, data) => {
    const allWindows = BrowserWindow.getAllWindows();
    allWindows.forEach(window => {
      if (window !== mainWindow) {
        window.destroy();
      }
    });

    // 发送logout消息到渲染进程
    mainWindow.webContents.send('logout');

    // 重置窗口状态
    mainWindow.setResizable(true);
    mainWindow.setMaximizable(false);

    // 退出全屏状态
    if (mainWindow.isFullScreen()) {
      mainWindow.setFullScreen(false);
    }

    // 设置最小尺寸为目标尺寸，确保可以缩小
    mainWindow.setMinimumSize(login_width, login_height);

    // 直接设置窗口大小和位置
    mainWindow.setSize(login_width, login_height);
    mainWindow.center();

    // 单次延时完成最终设置

    mainWindow.setMinimumSize(1, 1); // 清除最小尺寸限制
    mainWindow.setResizable(false);

  });

  // 通话
  ipcMain.on('call' , (event, data) => {
    const { type , targetUserId , sessionId} = data
    CallUtil.startCall(sessionId ,userStore.uid, userStore.nickName , null, (param) => {
      console.log('房子状态更新啦：' , param)
      const route = `/call/${targetUserId}/${sessionId}/${type}/0`
      if (param.state === 2) {
        createNewWindow(route ,
          null , {width: 360 , height: 640})
      } else if (param.state === 0) {
        if ( childWindows[route]) {
          childWindows[route].destroy();
        }
      }
    })

  })

  // 收到通话申请
  ipcMain.on('receiveCall' , (event, data) => {
    const { type , targetUserId , sessionId} = data
    createCallNotificationWindow(`/notice/call/${targetUserId}/${sessionId}/${type}`)
  })

  // 挂断通话
  ipcMain.on('stopCall' , (event, data) => {
    mainWindow.webContents.send('stopCall' , data);
    operateWindow(event , 'close')
  })

  // 接收方挂断通话
  ipcMain.on('stopCallByReceiver' , (event, data) => {
    if (childWindows['noticeCall']) {
      const noticeCallWindow = childWindows['noticeCall']
      noticeCallWindow.destroy()
      delete noticeCallWindow['noticeCall']
    }
  })


  // 接受通话
  ipcMain.on('acceptCall' , (event, data) => {
    const { type , targetUserId , sessionId} = data
    createNewWindow(`/call/${targetUserId}/${sessionId}/${type}/1` , null , {width: 360 , height: 640})
  })

  // 创建通话提醒窗口
  function createCallNotificationWindow(route) {
    const { screen } = require('electron')
    const notificationWindow = new BrowserWindow({
      width: 300,
      height: 120,
      show: false,
      frame: false,
      alwaysOnTop: true,
      resizable: false,
      skipTaskbar: true,
      transparent: true,
      webPreferences: {
        contextIsolation: false,
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false
      }
    })

    // 获取屏幕工作区域尺寸并定位到右下角（自动排除任务栏）
    const primaryDisplay = screen.getPrimaryDisplay()
    const { x: workAreaX, y: workAreaY, width: workAreaWidth, height: workAreaHeight } = primaryDisplay.workArea

    const windowWidth = 300
    const windowHeight = 120
    const margin = 0

    notificationWindow.setPosition(
      workAreaX + workAreaWidth - windowWidth - margin,
      workAreaY + workAreaHeight - windowHeight - margin
    )

    // 加载页面
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      notificationWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/#${route}`)
    } else {
      notificationWindow.loadFile(join(__dirname, '../renderer/index.html'), {
        hash: route
      })
    }

    notificationWindow.on('ready-to-show', () => {
      notificationWindow.show()
    })

    childWindows['noticeCall'] = notificationWindow;
    return notificationWindow
  }

}


let contactService = null
let sessionService = null
let messageService = null
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  messageService = new MessageService()
  contactService = new ContactService()
  sessionService = new SessionService()
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
